﻿using System;
using System.Collections.Generic;
using System.Linq;
using Sustainalytics.CRT.Synchronization.Exception;
using Sustainalytics.ESG.Entities;

namespace Sustainalytics.CRT.Synchronization
{
    public class FocusedRatingsCompanyScoreCalculator
    {
        public FocusedRatingsCompanyScoreManager.FocusedRatingsPerformance GetScore(double? indent, Dictionary<string, double> weights, Dictionary<string, int> rawScores)
        {
            var result = new FocusedRatingsCompanyScoreManager.FocusedRatingsPerformance();

            var score = weights.Aggregate(0d,
                (accumulator, weight) =>
                {
                    var rawScore = GetIndicatorRawScore(rawScores, weight);

                    result.Indicators.Add(new RPIndicatorPerformance
                    {
                        Code = weight.Key,
                        RawScore = Convert.ToSingle(rawScore),
                        Weight = Convert.ToSingle((double)weight.Value),
                        WeightedScore = Convert.ToSingle(rawScore * weight.Value)
                    });

                    return accumulator + (weight.Value * rawScore);
                });

            result.WeightedScore = CapScore(score + indent.GetValueOrDefault());

            return result;
        }

        private static double CapScore(double score)
        {
            if (score < 0)
            {
                return 0;
            }

            if (score > 100)
            {
                return 100;
            }

            return score;
        }

        private static double GetIndicatorRawScore(IReadOnlyDictionary<string, int> rawScores, KeyValuePair<string, double> indicator)
        {
            if (!rawScores.ContainsKey(indicator.Key))
            {
                throw new IndicatorNotFoundException(indicator.Key);
            }

            return rawScores[indicator.Key];
        }
    }
}